using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace LS.UnityExtensions
{
    public abstract class PreloadScriptableObjectSingleton<T> : PreloadScriptableObject where T : PreloadScriptableObjectSingleton<T>
    {
        private static PreloadScriptableObjectSingleton<T> m_Instance = null;
        
        public static T InstanceObject
        {
            get
            {
                #if UNITY_EDITOR
                m_Instance = LoadConfig();
                #endif
                return (T)m_Instance;
            }

            set
            {
                #if UNITY_EDITOR
                var type = typeof(T);
                EditorBuildSettings.AddConfigObject(type.Name, value, true);
                #endif
                m_Instance = value;
            }
        }
        
        #if UNITY_EDITOR
        private void OnEnable()
        {
            if (InstanceObject == this)
            {
                return;
            }

            if (InstanceObject && InstanceObject != null)
            {
                Debug.LogError($"Multiple {this.GetType().Name} asset NOT allowed!");
                return;
            }
            var config = LoadConfig();
            if (config)
            {
                m_Instance = config;
            }
        }

        private static T LoadConfig()
        {
            T config = null;
            var type = typeof(T);
            if (!EditorBuildSettings.TryGetConfigObject(type.Name, out config))
            {
                foreach (var item in AssetDatabase.FindAssets($"t:{type.Name}"))
                {
                    string path = AssetDatabase.GUIDToAssetPath(item);
                    config = AssetDatabase.LoadAssetAtPath<T>(path);
                    break;
                }
            }
            else
            {
                T configAsset = null;
                foreach (var item in AssetDatabase.FindAssets($"t:{type.Name}"))
                {
                    string path = AssetDatabase.GUIDToAssetPath(item);
                    configAsset = AssetDatabase.LoadAssetAtPath<T>(path);
                    break;
                }

                if(configAsset == null)
                {
                    EditorBuildSettings.RemoveConfigObject(type.Name);
                    config = null;
                }
            }
            return config;
        }
        
        #else
        private void Awake()
        {
            var type = typeof(T);
            Debug.Log($"{type.Name} awakening...");
            if (InstanceObject && InstanceObject != null)
            {
                Debug.LogError($"Multiple {type.Name} instance NOT allowed!");
            }
            
            if (!m_Instance)
            {
                m_Instance = this;
                DontDestroyOnLoad(m_Instance);
            }
        }
#endif
    }
}
